#include "app_device.h"
#include "fcntl.h"
#include "stdio.h"
#include "unistd.h"
#include "app_pool.h"
#include "app_message.h"
#include "app_mqtt.h"
#include "app_common.h"
#include <stdlib.h>
#include "log.h"

/**
 * 初始化设备结构体
 */
Device *app_device_init(char *dev_filename)
{
    // 1 初始化设备结构体 开辟空间
    Device *device = (Device *)malloc(sizeof(Device));
    if (device == NULL)
    {
        log_error("malloc device error\n");
    }
    // 2 设置默认值
    device->dev_filename = dev_filename;
    int fd = open(dev_filename, O_RDWR);
    device->fd = fd;
    device->conn_type = CONN_TYPE_NONE;
    device->dev_type = DEVICE_TYPE_NONE;
    device->up_buffer = app_buffer_init(1024);
    device->down_buffer = app_buffer_init(1024);
    device->is_running = 0;
    device->last_write_ts_ms = 0;
    device->interval_ms = 100;
    device->post_read = NULL;
    device->pre_write = NULL;

    return device;
}

/**
 * 启动设备运行 ，开始读取芯片数据的线程 ，执行（从芯片中读取数据到上行缓冲区）
 * 1 创建一个单独线程用于读取芯片数据
 * 2 设置设备运行标志位
 */
int app_device_start(Device *device)
{
    if (device->is_running)
    {
        log_warn("设备已经启动..");
        return 0;
    }
    // 运行设备
    int ret = pthread_create(&device->read_thread, NULL, app_device_read, device);
    if (ret != 0)
    {
        log_error("创建设备启动线程失败..");
    }
    device->is_running = 1;
    log_warn("设备已经启动..");
    return 0;
}

/**
 * 从芯片中读取数据到上行缓冲区 （异步）
 * 1 从设备 文件中读取数据
 * 2 对数据进行读后预处理 把e设备格式转换为字节数组
 * 3 把字节数组写入上行缓冲区
 * 4 把数据发送到mqtt的方法和参数提交给线程池
 *
 */
void *app_device_read(void *arg)
{   Device *device= (Device *)arg;
    char read_buff[100] = {0};
    //* 1 从设备 文件中读取数据
    while (device->is_running)
    { // 阻塞状态读取，有数据直接返回，没有数据阻塞等待
        ssize_t real_read_size = read(device->fd, read_buff, 100);
        //* 2 对数据进行[读后预处理] 把e设备格式转换为字节数组

        if (real_read_size > 0 && device->post_read) 
        {   
            real_read_size = device->post_read(read_buff, real_read_size);
        }
        //* 3 把字节数组写入上行缓冲区
        if (real_read_size > 0)
        {
 
            log_info("写入到缓冲区：");
            app_common_print_hex(read_buff, real_read_size);
            app_buffer_write(device->up_buffer, read_buff, real_read_size);

            //* 4 把数据发送到mqtt的方法和参数提交给线程池
            app_pool_add_task(app_device_send_to_mqtt, device);
        }
    }
    return NULL;
}

/**
 * 从上行缓冲区中读取数据到消息队列 (交给线程池执行 异步方法)
 * 1 读取缓冲区的数据
 * 2 把字节数组格式n转为 json格式
 * 3 把json格式数据发送到mqtt
 */
void *app_device_send_to_mqtt(void *arg)
{   Device *dev=(Device *)arg;
    char read_buff[100];
    // * 1 读取缓冲区的数据
    // 读取帧头数据
    app_buffer_read(dev->up_buffer, read_buff, 3);
    // 读取主体数据
    int payload_len = read_buff[1] + read_buff[2]; // id_len +msg_len
    app_buffer_read(dev->up_buffer, read_buff + 3, payload_len);
    int real_read_size = 3 + payload_len;

    //* 2 把字节数组格式转为 json格式
    Message *message = app_message_bytes_to_message(read_buff, real_read_size);
    char *json = app_message_message_to_json(message);
    //* 3 把json格式数据发送到mqtt
    log_info("即将发送的数据:%s", json);
    int ret = app_mqtt_send(json);
    if (ret == 0)
    {
        log_info("数据发生成功 ");
    }
    return NULL;
}

/**
 * 接收路由模块接收消息后 传递给设备模块
 */
int app_device_recv_from_mqtt(Device *dev, Message *msg);

/**
 * 从设备模块的a下行缓冲区 写入芯片中 （异步 由线程池执行）
 */
void *app_device_write(void *dev);

/**
 * 销毁设备结构体
 */
void app_device_destroy(Device *dev);